#include "defs.h"       // 当前项目的头文件，包含uart_putc等声明
#include "types.h"      // 确保有uint64等类型定义
#include "stdarg.h"     // 处理可变参数
#include <stddef.h>     // 用于NULL

// 数字转换用的字符表
static const char digits[] = "0123456789ABCDEF";

// 函数指针类型：字符输出函数（复用旧逻辑）
typedef void (*putc_func)(char c, void *ctx);

// sprintf 上下文结构体（如需sprintf功能保留，否则可删除）
struct sprintf_ctx {
    char *buf;
    int pos;
};

// 提前声明内部函数
static void print_number(putc_func putc, void *ctx, uint64 num, int base, int is_signed);
static void sprintf_putc(char c, void *ctx);

// 数字转换核心函数（复用旧逻辑，微调参数）
static void print_number(putc_func putc, void *ctx, uint64 num, int base, int is_signed) {
    char buf[32];
    int i = 0;
    int64 s_num;

    if (is_signed && (int64)num < 0) {
        s_num = (int64)num;
        num = (uint64)(-s_num);
        putc('-', ctx);
    }

    if (num == 0) {
        buf[i++] = '0';
    } else {
        while (num > 0) {
            buf[i++] = digits[num % base];
            num /= base;
        }
    }

    while (i > 0) {
        putc(buf[--i], ctx);
    }
}

// 缓冲区输出回调（用于sprintf，不需要可删除）
static void sprintf_putc(char c, void *ctx) {
    struct sprintf_ctx *sctx = (struct sprintf_ctx*)ctx;
    sctx->buf[sctx->pos++] = c;
}

// 通用格式化输出函数（核心逻辑）
static void vprintfmt(putc_func putc, void *ctx, const char *fmt, va_list ap) {
    for (; *fmt; fmt++) {
        if (*fmt != '%') {
            putc(*fmt, ctx);
            // 补充换行时的回车（适配当前项目的uart行为）
            if (*fmt == '\n') putc('\r', ctx);
            continue;
        }
        fmt++;
        
        switch (*fmt) {
            case 'd': {  // 十进制整数
                int num = va_arg(ap, int);
                print_number(putc, ctx, (uint64)num, 10, 1);
                break;
            }
            case 'x': {  // 十六进制（无符号）
                uint32 num = va_arg(ap, uint32);
                print_number(putc, ctx, (uint64)num, 16, 0);
                break;
            }
            case 'p': {  // 指针地址（十六进制，带0x前缀）
                uint64 ptr = va_arg(ap, uint64);
                putc('0', ctx);
                putc('x', ctx);
                print_number(putc, ctx, ptr, 16, 0);
                break;
            }
            case 's': {  // 字符串
                const char *s = va_arg(ap, const char*);
                if (!s) s = "(null)";
                for (; *s; s++) putc(*s, ctx);
                break;
            }
            case 'c': {  // 字符
                int c = va_arg(ap, int);
                putc((char)c, ctx);
                break;
            }
            case '%': {  // 输出%
                putc('%', ctx);
                break;
            }
            default: {  // 未知格式符
                putc('%', ctx);
                putc(*fmt, ctx);
                break;
            }
        }
    }
}

// 格式化输出到UART（核心：将console_putc替换为uart_putc）
int printf(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    // 用当前项目的uart_putc作为输出函数，上下文为NULL
    vprintfmt((putc_func)uart_putc, NULL, fmt, ap);
    va_end(ap);
    return 0;
}

// （可选）保留sprintf功能（如需格式化字符串到缓冲区）
int sprintf(char *buf, const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    
    struct sprintf_ctx ctx = {.buf = buf, .pos = 0};
    vprintfmt(sprintf_putc, &ctx, fmt, ap);
    buf[ctx.pos] = '\0';
    
    va_end(ap);
    return ctx.pos;
}